﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Reflection;
using System.ServiceProcess;
using System.Text;
using System.Timers;
using TruyenTranhCrawler.Data;
using log4net;
using log4net.Config;

namespace TruyenTranhCrawler
{
    public partial class ServiceTruyen : ServiceBase
    {
        private static readonly ILog Logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

        private double _interval;//in minute
        public ServiceTruyen()
        {
            XmlConfigurator.Configure();
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            Logger.Info("Crawler in OnStart.");

            _interval = Convert.ToDouble(ConfigurationManager.AppSettings["WaitMinutes"]) * 60000;

            _time = new Timer { Interval = 1000 };
            _time.Elapsed += TimeElapsed;
            _time.Start();
        }

        protected override void OnStop()
        {
            Logger.Info("Stopped.");
        }

        private Timer _time;
        private void TimeElapsed(object sender, ElapsedEventArgs e)
        {
            //stop timer task
            _time.Enabled = false;
            _time.Stop();
            _time.Close();

            //run services at first
            RunService();

            //start new task
            _time = new Timer { Interval = _interval };
            _time.Elapsed += TimeElapsed;
            _time.Start();
        }

        private void RunService()
        {
            List<Book> books;
            int totalNewChap = 0;
            if (Config.CanCrawlBlogTruyen)
            {
                Logger.Info("blogtruyen start...");
                //host is blogtruyen
                if (!Config.UpdateBookOnly)
                {
                    //lay danh sach the loai, co the goi nhieu lan de them nhung cai moi
                    BlogTruyen.Instance.GetBookTypes();

                    //lay truyen moi, chi gom cac thong tin co ban, chua save        
                    books = BlogTruyen.Instance.GetNewBooks();
                    //them vao nhung Book da ton tai nhung chua finish
                    books.AddRange(Book.GetWaitingBooks());
                    Logger.Info(string.Format("Them ca book chua finish, tong cong: {0}", books.Count));
                }
                else
                {
                    //kiem tra xem co truyen moi update khong?, neu co thi lay danh sach update do
                    books = BlogTruyen.Instance.GetUpdatedBooks();
                }

                //Lay danh sach Chap moi
                totalNewChap += books.Sum(book => BlogTruyen.Instance.GetNewChaps(book));

                Logger.Info("Xong blogtruyen.");
            }

            if (Config.CanCrawlComicVn)
            {
                Logger.Info("comicvn start...");
                //host is ComicVn.net
                books = ComicVn.Instance.GetBooks();

                totalNewChap += books.Sum(book => ComicVn.Instance.GetNewChaps(book));

                Logger.Info("Xong comicvn.");
            }
            
            if (Config.CanCrawlVitaku)
            {
                Logger.Info("Vitaku start...");
                Vitaku.Instance.GetBooks();
                Logger.Info("Xong Vitaku.");
            }

            if (totalNewChap > 0)
            {
                //ghi ra file log update, de tu dong recached
                SaveUpdatedLog();
            }
            Logger.Info("Done. Wait for next turn");
        }
        //
        //        List<Data.Book> AddRangeWithouDuplicate(List<Data.Book> list1, IEnumerable<Book> list2)
        //        {
        //            var merged = new List<Data.Book>(list1);
        //            merged.AddRange(list2.Where(x2 => list1.All(x1 => x1.ID != x2.ID)));
        //            return merged;
        //        }


        void SaveUpdatedLog()
        {
            var absPath = Config.LogUpdatedPath;
            //write new values
            if (!Directory.Exists(absPath))
                Directory.CreateDirectory(Path.GetDirectoryName(absPath));
            using (var w = new StreamWriter(absPath, false))
            {
                w.WriteLine(DateTime.Now.ToString("dd/MM/yyyy HH:mm"));
            }
        }
    }
}
